Skip to content

Feat/group feature#12

Merged
Weinsen merged 5 commits into
v0.0.8-rcfrom
feat/group-feature
May 18, 2026
Merged

Feat/group feature#12
Weinsen merged 5 commits into
v0.0.8-rcfrom
feat/group-feature

Conversation

@Weinsen

@Weinsen Weinsen commented May 18, 2026

Copy link
Copy Markdown
Owner

Summary

Add hierarchical command grouping to the prompter, improve runtime stability around interrupts and help output, and expand the examples, tests, and documentation so grouped command paths are supported and documented end to end.

What Changed

  • Added grouped command support through CommandGroup, including nested path registration, grouped command resolution, grouped help output, and nested prompt completions.
  • Enabled spaced command paths such as motor start and motor axis move, with conflict checks when a command or group path is already occupied.
  • Improved prompter runtime behavior around Ctrl+C with graceful shutdown on first interrupt and forced exit on the second interrupt.
  • Improved runtime help output so the interactive prompt no longer exposes API docstring sections like Args: and Returns:.
  • Tightened parameter handling and validation, including better casting errors and dynamic option coverage.
  • Added a runnable grouped-command example and refreshed user/API documentation for grouped command paths.
  • Removed the stale temporary example file and updated package/docs metadata touched by the branch.
  • Expanded test coverage across base prompter behavior, grouped commands, completer behavior, parameter casting, and prompt interrupt handling.

Type of Change

  • Feature: Introduces grouped command functionality without breaking changes
  • Enhancement: Improves prompt completion, runtime behavior, and documentation
  • Bugfix: Fixes runtime help output and error handling regressions
  • Documentation: Updates examples and user-facing documentation

Validation

  • ./tools/format.sh
  • source .venv/bin/activate && ./tools/lint.sh --changed
  • source .venv/bin/activate && pytest -q
  • source .venv/bin/activate && python -m sphinx -b html docs docs/_build/html
  • source .venv/bin/activate && python -m build

Notes for Reviewers

  • The main review areas are the grouped command registry/resolution flow in BasePrompter/CommandGroup, the nested completer wiring in Prompter, and the new regression coverage around grouped paths and interrupt handling.
  • The Sphinx build succeeds, but it still reports two existing warnings: the missing _static docs path and the prompt_toolkit forward-reference warning from sphinx_autodoc_typehints.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces hierarchical command grouping to cmdcraft via a new CommandGroup class, enabling spaced command paths (e.g. motor axis move). It also reworks the BasePrompter registry/resolution flow, extends the prompt-toolkit Prompter to build nested completers, hides API docstring sections from interpreter help, and ships an example plus refreshed documentation and tests.

Changes:

  • Add CommandGroup with path-aware register_group/register_command/resolve/command_paths and integrate it into BasePrompter as the root registry, plus grouped-help formatting and conflict detection.
  • Build the prompt-toolkit NestedCompleter recursively from the group tree so grouped paths complete correctly.
  • Expand tests for grouped paths, nested completion, help behavior, and conflict errors; add a runnable grouped-command example and update docs/README.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/cmdcraft/group.py New CommandGroup plus path helpers powering registration and resolution.
src/cmdcraft/base.py Route registration/resolution through _root_group; rework interpret and help to handle paths and group help.
src/cmdcraft/prompter.py Recursive nested completer from group tree, updated docstrings/license header.
src/cmdcraft/init.py Export CommandGroup, bump version to 0.0.8, add license header.
test/test_base.py Coverage for grouped command paths, group/command conflicts, and help filtering.
test/test_prompter.py Coverage for nested completion on grouped command paths.
examples/group_commands.py New runnable example demonstrating grouped command registration.
examples/tmp.py Removes stale temporary example.
docs/pages/howto/crafting.rst New "Command Grouping" section with usage example (indentation issues flagged).
docs/pages/documentation.rst Adds cmdcraft.group API reference.
README.rst Mentions nested command groups feature.
.gitignore Adds eggs, .github/, .vscode/ (the .github/ entry is flagged).
Comments suppressed due to low confidence (1)

docs/pages/howto/crafting.rst:79

  • The code block in this documentation section has inconsistent indentation that makes it invalid Python. Inside async def main(), the body starts at 8 spaces ( prompt = Prompter()) but the subsequent statements use 6 spaces ( project = prompt.register_group(...), config = ..., etc.), and await prompt.run() reverts to 8 spaces. A user copy-pasting this snippet will get an IndentationError. Please normalize the indentation of all statements inside main() to the same level (4 spaces under async def main() is the convention used by the rest of the example).
    async def main() -> None:
        prompt = Prompter()

      project = prompt.register_group("project", doc="Project commands.")
      project.register_command(start)
      project.register_command(status)

      config = prompt.register_group(
        "project config",
        doc="Project configuration commands.",
      )
      config.register_command(show)
      prompt.register_command(set_value, alias="project config set")

      profiles = prompt.register_group(
        "project profile",
        doc="Project profile commands.",
      )
      profiles.register_command(list_profiles, alias="list")

        await prompt.run()

    asyncio.run(main())

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +43 to +75
print("project started")

async def status() -> None:
print("project status shown")

async def show() -> None:
print("project configuration shown")

async def set_value(key: str, value: str) -> None:
print(f"project configuration updated: {key}={value}")

async def list_profiles() -> None:
print("profiles: dev, test, prod")

async def main() -> None:
prompt = Prompter()

project = prompt.register_group("project", doc="Project commands.")
project.register_command(start)
project.register_command(status)

config = prompt.register_group(
"project config",
doc="Project configuration commands.",
)
config.register_command(show)
prompt.register_command(set_value, alias="project config set")

profiles = prompt.register_group(
"project profile",
doc="Project profile commands.",
)
profiles.register_command(list_profiles, alias="list")
@Weinsen
Weinsen merged commit 0bac5d1 into v0.0.8-rc May 18, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants